﻿
using Fleck;
using Skybot.Net.WebSockets.Sockets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Skybot.Net.WebSockets
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        MainWindowModel model = new MainWindowModel();

        SkybotWebSocket webSocket = new SkybotWebSocket();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = model;
            Loaded += MainWindow_Loaded;
        }

#if SuperWebSocket
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Loaded -= MainWindow_Loaded;

            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                var appServer = new SuperWebSocket.WebSocketServer();

                //Setup the appServer
                if (!appServer.Setup(8181)) //Setup with listening port
                {
                    Console.WriteLine("Failed to setup!");
                    return;
                }

                appServer.NewMessageReceived += new SuperSocket.SocketBase.SessionHandler<SuperWebSocket.WebSocketSession, string>(appServer_NewMessageReceived);

                Console.WriteLine();

                //Try to start the appServer
                if (!appServer.Start())
                {
                    Console.WriteLine("Failed to start!");
                    return;
                }

                Console.WriteLine("The server started successfully, press key 'q' to stop it!");

                while (Console.ReadKey().KeyChar != 'q')
                {
                    Console.WriteLine();
                    continue;
                }

            });





        }
        long n;

        void appServer_NewMessageReceived(SuperWebSocket.WebSocketSession session, string message)
        {
            if (!string.IsNullOrEmpty(message))
            {
                //Send the received message back
                session.Send("Server: " + session.RemoteEndPoint + "  " + message + "  " + n);
            }
            System.Threading.Interlocked.Increment(ref n);
        }

#endif
#if FleckWebSocket
        #region Socket状态相关


        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Loaded -= MainWindow_Loaded;
            webSocket.Start(model.Status = "ws://0.0.0.0:8181");
            webSocket.OnAccpeted += webSocket_OnAccpeted;
            webSocket.OnClosed += webSocket_OnClosed;

        }

        /// <summary>
        /// 接入的客户端用户
        /// </summary>
        System.Collections.Concurrent.ConcurrentDictionary<string, Fleck.WebSocketConnection> WebSocketClients = new System.Collections.Concurrent.ConcurrentDictionary<string, Fleck.WebSocketConnection>();

        /// <summary>
        /// 用户关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void webSocket_OnAccpeted(object sender, RoutedPropertyChangedEventArgs<Fleck.WebSocketConnection> e)
        {
            var conn = e.NewValue;
            string key = GetEpKey(conn);
            if (WebSocketClients.TryAdd(key, conn))
            {
                Console.WriteLine(string.Format("Open! {0}", key));
                RecClass rec = new RecClass() { conn = conn, key = key };
                //接收到数据
                conn.OnMessage = rec.OnReceived;
            }
        }

        /// <summary>
        /// 用户 接入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void webSocket_OnClosed(object sender, RoutedPropertyChangedEventArgs<Fleck.WebSocketConnection> e)
        {
            var conn = e.NewValue;
            string key = GetEpKey(conn);
            if (WebSocketClients.TryRemove(key, out conn))
            {
                Console.WriteLine(string.Format("Close! {0}", key));
            }
        }
        /// <summary>
        /// 获取当前联接节点的Key
        /// </summary>
        /// <returns></returns>
        protected string GetEpKey(WebSocketConnection conn)
        {

            return string.Format("{0}:{1}", conn.Socket.RemoteIpAddress, conn.Socket.RemotePort.ToString("D5"));
        }



        protected class RecClass
        {
            protected long n;

            public WebSocketConnection conn { get; set; }
            public string key { get; set; }

            public void OnReceived(string message, WebSocketConnection conn)
            {
                ReceiveClientString(conn, key, message);
            }
            /// <summary>
            /// 接收到客户端发送过来的数据
            /// </summary>
            /// <param name="conn"></param>
            /// <param name="message"></param>
            protected void ReceiveClientString(WebSocketConnection conn, string key, string message)
            {

                if (!string.IsNullOrEmpty(message))
                {
                    conn.Send(string.Format("接收到节点{0},数据:{1},接收时间:{2},    {3}", key, message, DateTime.Now, n));
                }
                System.Threading.Interlocked.Increment(ref n);
            }

        }


        #endregion
#endif


        /// <summary>
        /// 异步发送帮肋类
        /// </summary>
        AsyncSocketSendHelper asyncSend = new AsyncSocketSendHelper();

        private void Button_Click(object sender, RoutedEventArgs e)
        {

            WebSocketHost host = new WebSocketHost();
            System.Net.IPEndPoint ep = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 8118);
            host.Start(ep);
            host.OnReceivedString = ReceiveData;
            model.Status = string.Format("WebSocket服务启动邦定端口{0}", ep);


        }

        System.Collections.Concurrent.ConcurrentQueue<string> imgqueue = new System.Collections.Concurrent.ConcurrentQueue<string>();

        public void ReceiveData(SocketClientConnection conn, string message)
        {
            if (!string.IsNullOrEmpty(message))
            {
                StringBuilder sb = new StringBuilder();
                //sb.Append(strx);
                //for (int n = 0; n < 199; n++)
                //{
                //    //输出大于64Kb的数据
                //    sb.AppendLine(n + " " + strx + "<br/>");
                //}
                string imgstr = string.Empty;
                int num = message.IndexOf("^img=");
                if (num != -1 || imgqueue.Count > 0)
                {
                    if (message.Length > num + 4 + 1 && imgqueue.Count == 0)
                    {
                        string sx = message.Substring(num + 4 + 1);
                        //结束位置
                        int num2 = sx.IndexOf("^");
                        if (num2 == -1)
                        {
                            imgqueue.Enqueue(sx);
                        }
                        else
                        {
                            lock (imgqueue)
                            {
                                //最后一包数据
                                string s = sx.Substring(0, num2);
                                imgqueue.Enqueue(s);

                                //base64图片
                                imgstr = string.Join(string.Empty, imgqueue.ToArray());

                                string tp = "";
                                while (imgqueue.Count > 0)
                                {
                                    imgqueue.TryDequeue(out tp);
                                }

                            }
                        }

                    }
                    else
                    {
                        //结束
                        int num2 = message.IndexOf("^");
                        if (num2 == -1)
                        {
                            imgqueue.Enqueue(message);
                        }
                        else
                        {
                            lock (imgqueue)
                            {
                                //最后一包数据
                                string s = message.Substring(0, num2);
                                imgqueue.Enqueue(s);

                                //base64图片
                                imgstr = string.Join(string.Empty, imgqueue.ToArray());

                                string tp = "";
                                while (imgqueue.Count > 0)
                                {
                                    imgqueue.TryDequeue(out tp);
                                }

                            }

                        }
                    }

                }
                if (string.IsNullOrEmpty(imgstr))
                {
                    var bytes = System.Text.UTF8Encoding.UTF8.GetBytes(string.Format("接收到节点{0},数据:{1},接收时间:{2}", conn.RemoteEndPoint, message, DateTime.Now) + sb.ToString()
                        + "<br/><span style='color:red;'>红色字----表示包结束</span>"
                        );

                    conn.Send(bytes, 65589, (arr) =>
                    {
                        asyncSend.SendToAsync(conn.Socket, arr);
                    });
                    sb.Clear();
                }
                else
                {
                    //显示图片

                    try
                    {
                        var byts = Convert.FromBase64String(imgstr);
                        var ms = new System.IO.MemoryStream(byts);
 
                        System.Threading.Tasks.Task.Factory.StartNew(() =>
                        {
                            Dispatcher.BeginInvoke(new Action(() =>
                           {
                               BitmapImage source = new BitmapImage();
                               source.BeginInit();
                               source.StreamSource = ms;
                               source.EndInit();
                               model.Iimg = source;
                               //img.Source = source;

                           }));
                        }).ContinueWith((t) =>
                        {
                            while (!ms.CanRead)
                            {
                                ms.Close();
                                ms.Dispose();
                                System.Threading.SpinWait.SpinUntil(() => false, 1);
                            }

                        });

                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                }


            }
        }

        public string strx = "WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口WebSocket服务启动邦定端口";
    }


    public class MainWindowModel : System.ComponentModel.INotifyPropertyChanged
    {
        private string _Status = string.Empty;


        public string Status
        {
            get { return _Status; }
            set
            {
                _Status = value;
                OnPropertyChanged("Status");
            }
        }


        private ImageSource _img = new BitmapImage();

        public ImageSource Iimg
        {
            get { return _img; }
            set
            {
                _img = value;
                OnPropertyChanged("Iimg");
            }
        }


        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 值改变时引发的事件
        /// </summary>
        /// <param name="name"></param>
        protected void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(name));
            }
        }
    }




}
